﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Runtime.CompilerServices;

using ConstructionBidOnline.DAL;
using ConstructionBidOnline.DAL.dsBidsTableAdapters;
using ConstructionBidOnline.Common;

namespace ConstructionBidOnline.Biz
{
    /// <summary>
    /// Bid Business Object
    /// </summary>

    public class Bid : BOBase
    {


        #region Construction / Disposal

        /// <summary>
        /// Default constructor.
        /// </summary>
        protected Bid() { }

        #endregion

        #region Public Properties

        #region Instance Properties

        /// <summary>
        /// PKID of the Bid.
        /// </summary>
        public int BidID
        {
            get { return _bidID; }
            set
            {
                if (_bidID != value)
                {
                    if (OnPropertyChanging("BidID", _bidID, value))
                    {
                        int oldValue = _bidID;
                        _bidID = value;

                        OnPropertyChanged("BidID", oldValue, value);
                    }
                }
            }
        }  private int _bidID = -1;

        /// <summary>
        /// JobID_RKJobs.
        /// </summary>
        public string JobID_RKJobs
        {
            get { return _jobID_RKJobs; }
            set
            {
                if (_jobID_RKJobs != value)
                {
                    if (OnPropertyChanging("JobID_RKJobs", _jobID_RKJobs, value))
                    {
                        string oldValue = _jobID_RKJobs;
                        _jobID_RKJobs = value;
                        OnPropertyChanged("JobID_RKJobs", oldValue, value);
                    }
                }
            }
        }  private string _jobID_RKJobs = null;


        /// <summary>
        /// CompanyID_RKRegisteredUser.
        /// </summary>
        public int CompanyID_RKRegisteredUser
        {
            get { return _companyID_RKRegisteredUser; }
            set
            {
                if (_companyID_RKRegisteredUser != value)
                {
                    if (OnPropertyChanging("CompanyID_RKRegisteredUser", _companyID_RKRegisteredUser, value))
                    {
                        int oldValue = _companyID_RKRegisteredUser;
                        _companyID_RKRegisteredUser = value;

                        OnPropertyChanged("CompanyID_RKRegisteredUser", oldValue, value);
                    }
                }
            }
        }  private int _companyID_RKRegisteredUser = -1;


        /// <summary>
        /// Date/time at which the Bid was created.
        /// </summary>
        public DateTime? BidDate
        {
            get { return _bidDate; }
            set
            {
                if (_bidDate != value)
                {
                    if (OnPropertyChanging("BidDate", _bidDate, value))
                    {
                        DateTime? oldValue = _bidDate;
                        _bidDate = value;
                        OnPropertyChanged("BidDate", oldValue, value);
                    }
                }
            }
        }  private DateTime? _bidDate = null;



        /// <summary>
        /// MessageInfo.
        /// </summary>
        public string MessageInfo
        {
            get { return _messageInfo; }
            set
            {
                if (_messageInfo != value)
                {
                    if (OnPropertyChanging("MessageInfo", _messageInfo, value))
                    {
                        string oldValue = _messageInfo;
                        _messageInfo = value;
                        OnPropertyChanged("MessageInfo", oldValue, value);
                    }
                }
            }
        }  private string _messageInfo = null;


        /// <summary>
        /// BidAmount.
        /// </summary>
        public decimal BidAmount
        {
            get { return _bidAmount; }
            set
            {
                if (_bidAmount != value)
                {
                    if (OnPropertyChanging("BidAmount", _bidAmount, value))
                    {
                        decimal oldValue = _bidAmount;
                        _bidAmount = value;
                        OnPropertyChanged("BidAmount", oldValue, value);
                    }
                }
            }
        }  private decimal _bidAmount = 0;



        /// <summary>
        /// BidStatus.
        /// </summary>
        public string BidStatus
        {
            get { return _bidStatus; }
            set
            {
                if (_bidStatus != value)
                {
                    if (OnPropertyChanging("BidStatus", _bidStatus, value))
                    {
                        string oldValue = _bidStatus;
                        _bidStatus = value;
                        OnPropertyChanged("BidStatus", oldValue, value);
                    }
                }
            }
        }  private string _bidStatus = null;


        /// <summary>
        /// BuyerNote.
        /// </summary>
        public string BuyerNote
        {
            get { return _buyerNote; }
            set
            {
                if (_buyerNote != value)
                {
                    if (OnPropertyChanging("BuyerNote", _buyerNote, value))
                    {
                        string oldValue = _buyerNote;
                        _buyerNote = value;
                        OnPropertyChanged("BuyerNote", oldValue, value);
                    }
                }
            }
        }  private string _buyerNote = null;




        /// <summary>
        /// Date/time at which the job was accepted or declined.
        /// </summary>
        public DateTime? AwardedOrDeclineDate
        {
            get { return _awardedOrdeclineDate; }
            set
            {
                if (_awardedOrdeclineDate != value)
                {
                    if (OnPropertyChanging("AwardedOrDeclineDate", _awardedOrdeclineDate, value))
                    {
                        DateTime? oldValue = _awardedOrdeclineDate;
                        _awardedOrdeclineDate = value;
                        OnPropertyChanged("AwardedOrDeclineDate", oldValue, value);
                    }
                }
            }
        }  private DateTime? _awardedOrdeclineDate = null;


        /// <summary>
        /// Reason.
        /// </summary>
        public string Reason
        {
            get { return _reason; }
            set
            {
                if (_reason != value)
                {
                    if (OnPropertyChanging("Reason", _reason, value))
                    {
                        string oldValue = _reason;
                        _reason = value;
                        OnPropertyChanged("Reason", oldValue, value);
                    }
                }
            }
        }  private string _reason = null;



        /// <summary>
        /// Attachment.
        /// </summary>
        public string Attachment
        {
            get { return _attachment; }
            set
            {
                if (_attachment != value)
                {
                    if (OnPropertyChanging("Attachment", _attachment, value))
                    {
                        string oldValue = _attachment;
                        _attachment = value;
                        OnPropertyChanged("Attachment", oldValue, value);
                    }
                }
            }
        }  private string _attachment = null;



        /// <summary>
        /// Date/time at which the job will start.
        /// </summary>
        public DateTime? JobStartDate
        {
            get { return _jobStartDate; }
            set
            {
                if (_jobStartDate != value)
                {
                    if (OnPropertyChanging("JobStartDate", _jobStartDate, value))
                    {
                        DateTime? oldValue = _jobStartDate;
                        _jobStartDate = value;
                        OnPropertyChanged("JobStartDate", oldValue, value);
                    }
                }
            }
        }  private DateTime? _jobStartDate = null;


        /// <summary>
        /// StartUpWithin.
        /// </summary>
        public string StartUpWithin
        {
            get { return _startUpWithin; }
            set
            {
                if (_startUpWithin != value)
                {
                    if (OnPropertyChanging("StartUpWithin", _startUpWithin, value))
                    {
                        string oldValue = _startUpWithin;
                        _startUpWithin = value;
                        OnPropertyChanged("StartUpWithin", oldValue, value);
                    }
                }
            }
        }  private string _startUpWithin = null;


        /// <summary>
        /// True iff the Bid is Active.
        /// </summary>
        public bool IsActive
        {
            get { return _isActive; }
            set
            {
                if (_isActive != value)
                {
                    if (OnPropertyChanging("IsActive", _isActive, value))
                    {
                        bool oldValue = _isActive;
                        _isActive = value;
                        OnPropertyChanged("IsActive", oldValue, value);
                    }
                }
            }
        }  private bool _isActive = false;

        #endregion

        #endregion

        #region Public Methods

        #region CreateNew

        /// <summary>
        /// Creates a new, empty Bid object.
        /// </summary>
        public static Bid CreateNew()
        {
            Bid obj = new Bid();

            // Switch state to Added prior to initializing property values.
            obj.ObjState = ObjectState.Added;

            obj.BidDate = DateTime.Now;
            obj.IsActive = true;
            return (obj);
        }


        [MethodImpl(MethodImplOptions.Synchronized)]
        public static Bid CreateNew(BidCollection collection)
        {
            Bid obj = CreateNew();

            // Get next/unique ID for the new object.
            int minVal = 0;
            foreach (Bid bid in collection)
            {
                if (bid.BidID < minVal)
                    minVal = bid.BidID;
            }
            obj.BidID = --minVal;
            collection.Add(obj);

            return (obj);
        }

        #endregion

        #region GetAllBid

        /// <summary>
        /// Returns a collection of all Bid.
        /// </summary>
        public static BidCollection GetAllBid()
        {
            BidTableAdapter adapter = new BidTableAdapter();
            adapter.Connection = AppSettings.GetDbConn();

            dsBids.BidDataTable tbl = adapter.GetData(null);

            BidCollection list = new BidCollection();

            if (tbl.Rows.Count > 0)
            {
                foreach (dsBids.BidRow row in tbl.Rows)
                {
                    Bid Bid = new Bid();
                    RelationalToObject(Bid, row);
                    list.Add(Bid);
                }
            }

            return (list);
        }

        #endregion

        #region GetBidByBidIsActive

        /// <summary>
        /// Returns a collection of all Bid.
        /// </summary>
        public static BidCollection GetBidByBidIsActive(bool isactive)
        {
            BidTableAdapter adapter = new BidTableAdapter();
            adapter.Connection = AppSettings.GetDbConn();

            dsBids.BidDataTable tbl = adapter.GetDataByBidIsActive(isactive);

            BidCollection list = new BidCollection();

            if (tbl.Rows.Count > 0)
            {
                foreach (dsBids.BidRow row in tbl.Rows)
                {
                    Bid Bid = new Bid();
                    RelationalToObject(Bid, row);
                    list.Add(Bid);
                }
            }

            return (list);
        }

        #endregion

        #region GetBidByBidID

        /// <summary>
        /// Returns an Bid object for the specified 'BidID' or null if no Bid with the specified parameter(s) exists.
        /// </summary>
        public static Bid GetBidByBidID(int bidid)
        {
            BidTableAdapter adapter = new BidTableAdapter();
            adapter.Connection = AppSettings.GetDbConn();
            dsBids.BidDataTable tbl = adapter.GetData(bidid);

            if (tbl.Rows.Count == 1)
            {
                Bid bid = new Bid();
                RelationalToObject(bid, tbl.Rows[0]);
                return (bid);
            }
            else if (tbl.Rows.Count > 1)
                throw new ApplicationException("Database integrity error: Specified 'BidID' returned more than one record.");

            return (null);
        }

        #endregion

        #region GetAllBidsByJobID

        /// <summary>
        /// Returns a collection of all Bid.
        /// </summary>
        public static BidCollection GetAllBidsByJobID(string jobid, bool bidstatus)
        {
            BidTableAdapter adapter = new BidTableAdapter();
            adapter.Connection = AppSettings.GetDbConn();

            dsBids.BidDataTable tbl = adapter.GetDataByJobID(jobid, bidstatus);

            BidCollection list = new BidCollection();

            if (tbl.Rows.Count > 0)
            {
                foreach (dsBids.BidRow row in tbl.Rows)
                {
                    Bid Bid = new Bid();
                    RelationalToObject(Bid, row);
                    list.Add(Bid);
                }
            }

            return (list);
        }

        #endregion

        #region GetBidByCompanyIDandJobID

        /// <summary>
        /// Returns an Bid object for the specified 'BidID' or null if no Bid with the specified parameter(s) exists.
        /// </summary>
        public static Bid GetBidByCompanyIDandJobID(string jobid, int companyid)
        {
            BidTableAdapter adapter = new BidTableAdapter();
            adapter.Connection = AppSettings.GetDbConn();
            dsBids.BidDataTable tbl = adapter.GetDataByCompanyIDandJobID(jobid, companyid);

            if (tbl.Rows.Count == 1)
            {
                Bid bid = new Bid();
                RelationalToObject(bid, tbl.Rows[0]);
                return (bid);
            }
            else if (tbl.Rows.Count > 1)
                throw new ApplicationException("Database integrity error: Specified 'BidID' returned more than one record.");

            return (null);
        }

        #endregion

        #region GetBidByCompanyID

        /// <summary>
        /// Returns a collection of all Bid.
        /// </summary>
        public static BidCollection GetBidByCompanyID(int contractorid)
        {
            BidTableAdapter adapter = new BidTableAdapter();
            adapter.Connection = AppSettings.GetDbConn();

            dsBids.BidDataTable tbl = adapter.GetDataByCompanyID(contractorid);

            BidCollection list = new BidCollection();

            if (tbl.Rows.Count > 0)
            {
                foreach (dsBids.BidRow row in tbl.Rows)
                {
                    Bid Bid = new Bid();
                    RelationalToObject(Bid, row);
                    list.Add(Bid);
                }
            }

            return (list);
        }

        #endregion

        #region Update

        /// <summary>
        /// Updates the specified Bid.
        /// </summary>
        public static void Update(Bid obj)
        {
            bool updateBid = false;

            // Do not update invalid objects.
            if (!obj.Validate())
            {
                StringBuilder sb = new StringBuilder(2048);
                sb.Append("The object being updated has one or more invalid properties; the Update() operation for this object has been cancelled.\nError(s):");
                foreach (ValidationError err in obj.Errors)
                    sb.Append("\n* " + err.Element + ": " + err.Message);

                throw new InvalidObjectException(sb.ToString());
            }
            else
            {
                updateBid = (obj.ObjState != ObjectState.Unchanged);

                if (!updateBid)
                    return;
            }

            ObjectState originalObjectState = obj.ObjState;

            dsBids.BidDataTable tbl = null;
            if (updateBid)
            {
                BidTableAdapter adapter = new BidTableAdapter();
                adapter.Connection = AppSettings.GetDbConn();

                tbl = new dsBids.BidDataTable();
                dsBids.BidRow row = tbl.NewBidRow();
                ObjectToRelational(obj, tbl, row);

                adapter.Update(tbl);

                if (originalObjectState == ObjectState.Deleted)
                    obj = null;
                else RelationalToObject(obj, tbl.Rows[0]);
            }
        }

        #endregion

        #region Validate

        /// <summary>
        /// Validates the object based on its properties at the time of the call; updates the Errors property.
        /// </summary>
        public override bool Validate()
        {
            Errors.Clear();

            if (ObjState == ObjectState.Unchanged)
            {
                // By definition, unchanged objects are valid.
                return (true);
            }
            else if (ObjState == ObjectState.Uninitialized)
            {
                Errors.Add(new ValidationError("object", "Object is uninitialized.", ValidationError.Severity.Error));

                // No need to proceed past this error.
                return (false);
            }
            else if ((ObjState == ObjectState.Deleted) && (BidID <= 0))
            {
                // Deleted items must have 'real' (i.e. non-negative, non-zero) key(s) to be valid.
                Errors.Add(new ValidationError("BidID", "Deleted object has an invalid PKID.", ValidationError.Severity.Error));

                // No need to proceed past this error.
                return (false);
            }
            else  // ObjState == Added | Modified
            {

                

            }

            return (Errors.Count == 0);
        }

        #endregion

        #region ToString

        /// <summary>
        /// User-friendly string represetation of this object.
        /// </summary>
        public override string ToString()
        {
            return (String.Format("Bid: BidID={0}, MessageInfo={1}", BidID, MessageInfo));
        }

        #endregion

        #endregion

        #region Privates


        #endregion

    }

    /// <summary>
    /// Collection of 0 or more Bid objects.
    /// </summary>

    public class BidCollection : List<Bid>
    {
        #region Types

        public class UserComparer : IComparer<Bid>
        {
            public int Compare(Bid b1, Bid b2)
            {
                return (String.Compare(b1.MessageInfo, b2.MessageInfo));
            }
        }

        #endregion

        #region Public Methods

        #region FindByBidID

        public Bid FindByBidID(int bidID)
        {
            for (int ndx = 0; ndx < this.Count; ndx++)
                if (this[ndx].BidID == bidID)
                    return (this[ndx]);

            return (null);
        }

        #endregion

        #region FindByBidStatus

        public Bid FindByBidStatus(string bidstatus)
        {
            for (int ndx = 0; ndx < this.Count; ndx++)
                if (this[ndx].BidStatus == bidstatus)
                    return (this[ndx]);

            return (null);
        }

        #endregion

        #endregion
    }
}
